/*
 * Copyright 2015 Hannes Dorfmann.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.baseproject.mvp.delegate;

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.baseproject.mvp.MvpBasePresenter;
import com.baseproject.mvp.MvpPresenter;
import com.baseproject.mvp.MvpView;

/**
 * * The default implementation of {@link FragmentMvpDelegate}
 *
 * @param <V> The type of {@link MvpView}
 * @param <P> The type of {@link MvpPresenter}
 * @author Hannes Dorfmann
 * @see FragmentMvpDelegate
 * @since 1.1.0
 */
public class FragmentMvpDelegateImpl<V extends MvpView, P extends MvpBasePresenter<V>>
        implements FragmentMvpDelegate<V, P> {

    public static boolean DEBUG = false;
    private static final String DEBUG_TAG = "FragmentMvpVSDelegate";

    private MvpDelegateCallback<V, P> delegateCallback;
    protected Fragment fragment;

    /**
     * @param fragment         The Fragment
     * @param delegateCallback the DelegateCallback
     */
    public FragmentMvpDelegateImpl(@NonNull Fragment fragment,
                                   @NonNull MvpDelegateCallback<V, P> delegateCallback) {
        if (delegateCallback == null) {
            throw new NullPointerException("MvpDelegateCallback is null!");
        }
        if (fragment == null) {
            throw new NullPointerException("Fragment is null!");
        }
        this.fragment = fragment;
        this.delegateCallback = delegateCallback;
    }


    @Override
    public void onViewCreated(View view, @Nullable Bundle bundle) {
        P presenter = delegateCallback.createPresenter();
        if (presenter == null) {
            throw new NullPointerException(
                    "Presenter returned from createPresenter() is null. Activity is " + getActivity());
        }
        delegateCallback.setPresenter(presenter);
        getPresenter().attachView(delegateCallback.getMvpView());
        getPresenter().start();
    }

    @NonNull
    private Activity getActivity() {
        Activity activity = fragment.getActivity();
        if (activity == null) {
            throw new NullPointerException(
                    "Activity returned by Fragment.getActivity() is null. Fragment is " + fragment);
        }
        return activity;
    }

    private P getPresenter() {
        P presenter = delegateCallback.getPresenter();
        if (presenter == null) {
            throw new NullPointerException("Presenter returned from getPresenter() is null");
        }
        return presenter;
    }

    private V getMvpView() {
        V view = delegateCallback.getMvpView();
        if (view == null) {
            throw new NullPointerException("View returned from getMvpView() is null");
        }
        return view;
    }

    protected boolean retainPresenterInstance() {
        return !fragment.isRemoving();
    }

    @Override
    public void onDestroyView() {
        getPresenter().detachView(false);
    }

    @Override
    public void onPause() {

    }

    @Override
    public void onResume() {

    }

    @Override
    public void onStart() {
    }

    @Override
    public void onStop() {

    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {

    }

    @Override
    public void onAttach(Activity activity) {

    }

    @Override
    public void onDetach() {

    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
    }

    @Override
    public void onCreate(Bundle saved) {
    }

    @Override
    public void onDestroy() {
        if (!getPresenter().subscriptions.isUnsubscribed()) {
            getPresenter().subscriptions.unsubscribe();
        }
    }

    @Override
    public void onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    }
}
